package testsystem;


import datautils.DataLoader;
import datautils.DataSaver;
import userdata.User;
import userdata.UserSession;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class DataBase {
    Map<User, List<UserSession>> userData;

    public DataBase() {
        this.userData = new DataLoader().readDB();
    }

    public void save() {
        DataSaver dataSaver = new DataSaver(userData);
        dataSaver.saveDB();
    }

    public User loginUser() {
        List<User> userList = getUserList();
        Scanner in = new Scanner(System.in);
        String userInput;
        User result = null;
        System.out.println("Введите логин:");
        while (result == null) { // TODO show message that no such user is present in db.
            userInput = in.nextLine();
            for (User elem: userList) {
                if (userInput.equals(elem.getLogin())) {
                    result = elem;
                    break;
                }
            }
        }
        checkPassword(result);
        return result;
    }

    private void checkPassword(User user) {
        Scanner in = new Scanner(System.in);
        System.out.println("Введите пароль:");
        String userInput;
        while (true) {
            userInput =  in.nextLine();
            if (user.isCorrectPassword(userInput)) {
                break;
            } else {
                System.out.println("Неправильный пароль, попробуйте еще!");
            }
        }
    }

    public User getUser() {
        if (userData.isEmpty()) {
            createAdmin();
        }
        return authorizeUser();
    }

    private void createAdmin() {
        User admin = new User("admin", "admin");
        userData.put(admin, null);
        save();
    }

    private User authorizeUser() {
        Scanner in = new Scanner(System.in);
        User user;
        System.out.println("Вы новый пользователь?(y/n)");
        if (in.nextLine().toLowerCase().equals("n")) {
            user = loginUser();
        } else {
            user = createNewUser();
        }
        return user;
    }

    private User createNewUser() {
        String login = createLogin();
        String pass = enterPassword();
        return new User(login, pass);
    }

    /**
     * Method takes password
     */
    private String enterPassword() {
        Scanner in = new Scanner(System.in);
        System.out.println("Введите пароль:");
        return in.nextLine();
    }

    private String createLogin() {
        Scanner in = new Scanner(System.in);
        String login;
        System.out.println("Введите логин:");
        while (true) {
            login = in.nextLine();
            if (!isExists(login)) {
                break;
            } else {
                System.out.println("Уже существует! попробуйте другой:");
            }
        }
        return login;
    }

    /**
     * Method is checking user's login for existence in DB.
     */
    private boolean isExists(String login) {
        List<User> userList = getUserList();
        for (User user: userList) {
            if (login.equals(user.getLogin())) {
                return true;
            }
        }
        return false;
    }

    private List<User> getUserList() {
        return new LinkedList<>(userData.keySet());
    }

    public UserSession getSession(User user) {
        UserSession result;
        if (userData.containsKey(user)) {
            List<UserSession> uSessions = userData.get(user);
            result = findSession(uSessions);
            if (result != null){
                return result;
            }
            return createNewSession(uSessions);
        } else {
            List<UserSession> uSessions = createNewUserSessionList(user);
            return createNewSession(uSessions);
        }
    }

    private UserSession findSession(List<UserSession> uSessions) {
        for (UserSession session: uSessions) {
            if (!session.isFinished()){
                return session;
            }
        }
        System.out.println("Незаконченных сессий не обнаружено!");
        return  null;
    }

    private UserSession createNewSession(List<UserSession> uSessions) {
        UserSession resultSession = new UserSession();
        uSessions.add(resultSession);
        return resultSession;
    }

    private List<UserSession> createNewUserSessionList(User user) {
        List<UserSession> uSessions = new LinkedList<>();
        userData.put(user, uSessions);
        return uSessions;
    }


    public void displayUsersAndSessions() {
        List<User> userList = new LinkedList<>(userData.keySet());
        int userIndex = 0;
        for (User user: userList) {
            System.out.printf("%d) %s%n", userIndex++, user.getLogin());
        }
        User chosenUser = chooseUser(userList);
        displaySessions(chosenUser);
    }

    private void displaySessions(User chosenUser) {
        int sessionIndex = 0;
        List<UserSession> uSessions = userData.get(chosenUser);
        if (uSessions == null) return; //TODO log empty sessions
        for (UserSession session: uSessions) {
            System.out.printf("Сессия намба %d\n", sessionIndex++);
            session.getResults();
            session.printResults();
        }
    }

    private User chooseUser(List<User> userList) {
        Scanner in = new Scanner(System.in);
        System.out.println("Choose user:");
        int input = in.nextInt();
        return userList.get(input);
    }
}
